<script setup lang="ts">
  import SingleAddress from '@/components/business/address/single-address/SingleAddress.vue'
  import useAddParser from '@/services/common/useAddParser'
  import { useGetCustomerOptions } from '@/services/pages/customer/useGetOptions'
  import { FormInstance } from 'element-plus'
  import _ from 'lodash'
  import { computed, ref } from 'vue'
  import { ArrowDown, ArrowUp } from '@element-plus/icons-vue'
  import { verifyPhone } from '@/utils/validate'

  const { addrParseResult, addrParseLoading, addrParse } = useAddParser()
  const {
    options: customerOptions,
    loading: getCustomerOptionsLoading,
    getOptionsParam: getCustomerOptionsParam,
    getOptions: getCustomerOptions,
  } = useGetCustomerOptions()

  defineOptions({
    name: 'ReceiptInfoReturnFactoryCreate',
  })

  type Form = Pick<ReturnFactoryAPIRequest.Create, 'receiveAddrVo'>['receiveAddrVo']

  // 是否与公司信息一致
  const isSameToCustomerInfo = ref(true)

  // 地址识别文本
  const addrParserVal = ref('')

  // 用户选择弹出框显示状态
  const customerSelectPopoverVisible = ref(false)

  // 地址选择组件实例
  const singleAddressRef = ref<InstanceType<typeof SingleAddress> | null>(null)

  // 表单
  const form = ref<Form>({
    customerReceiveAddress: '',
    customerReceiveArea: '',
    customerReceiveCity: '',
    customerReceivePhone: '',
    customerReceiveProvince: '',
    customerReceiveUsername: '',
    customerTakePieceMode: 2,
  })

  // 表单验证规则
  const rules = ref({
    customerReceiveAddress: [
      { required: true, message: '请输入详细地址', trigger: ['change', 'blur'] },
    ],
    customerReceivePhone: [
      { required: true, message: '请输入手机号', trigger: ['change', 'blur'] },
      {
        validator: (rule, value, callback) => {
          if (!verifyPhone(form.value.customerReceivePhone)) {
            callback(new Error('格式不正确'))
            return
          }
          callback()
        },
        trigger: ['change', 'blur'],
      },
    ],
    customerReceiveUsername: [
      { required: true, message: '请输入收货人名称', trigger: ['change', 'blur'] },
    ],
    customerReceiveProvince: [
      { required: true, message: '请选择地址', trigger: ['change', 'blur'] },
      {
        validator: (rule, value, callback) => {
          if (
            !form.value.customerReceiveProvince ||
            !form.value.customerReceiveArea ||
            !form.value.customerReceiveCity
          ) {
            callback(new Error('请选择地址'))
            return
          }
          callback()
        },
        trigger: ['change', 'blur'],
      },
    ],
  })

  // 地址回显，用于给SingleAddress组件显示选择的地址
  const addressEcho = computed(() => {
    return {
      province: form.value.customerReceiveProvince,
      area: form.value.customerReceiveArea,
      city: form.value.customerReceiveCity,
      town: '',
    }
  })

  // 表单组件实例
  const formInstance = ref<FormInstance | null>(null)

  /**
   * 获取收货人下拉选项
   */
  const handleChangeCustomerName = _.debounce((keyword: string) => {
    if (getCustomerOptionsParam.value.name !== keyword) {
      getCustomerOptionsParam.value.name = keyword
      getCustomerOptions()
      customerSelectPopoverVisible.value = true
    }
  }, 600)

  /**
   * 清空收货人信息
   */
  const clearCustomerInfo = () => {
    form.value = {
      customerReceiveAddress: '',
      customerReceiveArea: '',
      customerReceiveCity: '',
      customerReceivePhone: '',
      customerReceiveProvince: '',
      customerReceiveUsername: '',
      customerTakePieceMode: 2,
    }
    customerSelectPopoverVisible.value = false
  }

  /**
   * 选择收货人
   * @param {CustomerOption} customerOption - 收货人下拉选项
   */
  const handleSelectCustomer = (customerOption: CustomerOption) => {
    form.value = {
      customerReceiveAddress: customerOption.address,
      customerReceiveProvince: customerOption.province,
      customerReceiveCity: customerOption.city,
      customerReceiveArea: customerOption.area,
      customerReceiveUsername: customerOption.name,
      customerReceivePhone: customerOption.phone,
      customerTakePieceMode: form.value.customerTakePieceMode,
    }
    customerSelectPopoverVisible.value = false
  }

  /**
   * 地址识别方法
   */
  const addrParser = async () => {
    if (!addrParserVal.value.trim()) return
    await addrParse(addrParserVal.value.trim())
    form.value = {
      customerReceiveProvince: addrParseResult.value.province,
      customerReceiveCity: addrParseResult.value.city,
      customerReceiveArea: addrParseResult.value.area,
      customerReceiveUsername: addrParseResult.value.username,
      customerReceivePhone: addrParseResult.value.phone,
      customerReceiveAddress: addrParseResult.value.address,
      customerTakePieceMode: form.value.customerTakePieceMode,
    }
  }

  /**
   * 更新省市区
   * @param {Object} address - 省市区集合
   * @param {String} address.province - 省
   * @param {String} address.area - 市
   * @param {String} address.city - 区
   * @param {String} address.town - 镇
   */
  const handleChangeProvinceAreaCity = (address: {
    province: string
    area: string
    city: string
    town: string
  }) => {
    form.value.customerReceiveProvince = address.province
    form.value.customerReceiveArea = address.area
    form.value.customerReceiveCity = address.city
  }

  defineExpose({
    getCustomerOptions,
    getForm: async () => {
      if (formInstance.value) {
        try {
          await formInstance.value.validate()
          return form.value
        } catch (error) {
          return null
        }
      }
      return null
    },
    setForm: (param: Form) => {
      if (isSameToCustomerInfo.value) {
        Object.assign(form.value, param)
      }
    },
  })
</script>

<template>
  <div class="receipt-info-return-factory-create-wrapper">
    <div class="header">
      <div class="title">寄修人收货信息</div>
      <el-switch
        :model-value="!isSameToCustomerInfo"
        size="small"
        @change="isSameToCustomerInfo = !isSameToCustomerInfo"
      ></el-switch>
      <el-tooltip effect="dark" placement="top" content="开启后，可修改收货信息">
        <i class="iconfont icon-warning"></i>
      </el-tooltip>
    </div>
    <div v-if="!isSameToCustomerInfo" v-loading="addrParseLoading" class="form">
      <el-form
        ref="formInstance"
        label-width="85"
        inline-message
        :model="form"
        :rules="rules"
        label-position="top"
      >
        <!-- 地址识别 -->
        <el-form-item
          v-if="form.customerTakePieceMode === 2"
          label="地址识别"
          class="address-parser"
        >
          <el-input
            v-model.trim="addrParserVal"
            type="textarea"
            :resize="isSameToCustomerInfo ? 'none' : 'both'"
            maxlength="200"
            placeholder="粘贴整段信息到此文本框如：张三，15815151515，北京市市辖区石景山区中山路25号"
            show-word-limit
            :disabled="isSameToCustomerInfo"
          />
          <h-button type="primary" :disabled="isSameToCustomerInfo" @click="addrParser"
            >识别</h-button
          >
        </el-form-item>
        <div class="customer-name-phone">
          <template v-if="form.customerTakePieceMode === 2">
            <!-- 收货人名称 -->
            <el-form-item label="收货人名称" prop="customerReceiveUsername">
              <el-popover
                :visible="customerOptions.length > 0 && customerSelectPopoverVisible"
                placement="bottom"
                width="390"
              >
                <template #reference>
                  <el-input
                    v-model.trim="form.customerReceiveUsername"
                    placeholder="请输入收货人名称"
                    clearable
                    :disabled="isSameToCustomerInfo"
                    maxlength="20"
                    @input="handleChangeCustomerName"
                    @clear="clearCustomerInfo"
                    @blur="customerSelectPopoverVisible = false"
                  >
                    <template #suffix>
                      <div
                        class="user-select-popover-trigger-el"
                        @click="customerSelectPopoverVisible = !customerSelectPopoverVisible"
                      >
                        <el-icon v-if="!customerSelectPopoverVisible">
                          <arrow-down />
                        </el-icon>
                        <el-icon v-else>
                          <arrow-up></arrow-up>
                        </el-icon>
                      </div>
                    </template>
                  </el-input>
                </template>

                <div class="user-select-wrapper">
                  <div v-loading="getCustomerOptionsLoading" class="user-select">
                    <div
                      v-for="(userOption, index) in customerOptions"
                      :key="index"
                      class="customer-info"
                      @click="handleSelectCustomer(userOption)"
                    >
                      <div class="customer-name">
                        <h-tooltip-text
                          :text="userOption.name"
                          :max-width="160"
                          :height="32"
                          text-align="right"
                        ></h-tooltip-text>
                      </div>
                      <div class="customer-phone">{{ userOption.phone }}</div>
                    </div>
                  </div>
                </div>
              </el-popover>
            </el-form-item>

            <!-- 收货人手机号 -->
            <el-form-item label="收货人手机号" prop="customerReceivePhone">
              <el-input
                v-model.trim="form.customerReceivePhone"
                placeholder="请输入收货人手机号"
                :disabled="isSameToCustomerInfo"
                maxlength="11"
              />
            </el-form-item>
          </template>
        </div>
        <div v-if="form.customerTakePieceMode === 2" class="customer-address">
          <!-- 收货人地址 -->
          <el-form-item label="收货人地址" prop="customerReceiveProvince">
            <SingleAddress
              ref="singleAddressRef"
              :address="addressEcho"
              :disabled="isSameToCustomerInfo"
              @change="handleChangeProvinceAreaCity"
            />
          </el-form-item>

          <!-- 收货人详细地址 -->
          <el-form-item label="收货人详细地址" prop="customerReceiveAddress">
            <el-input
              v-model.trim="form.customerReceiveAddress"
              type="textarea"
              placeholder="请输入详细地址"
              resize="both"
              maxlength="200"
              show-word-limit
              :disabled="isSameToCustomerInfo"
            />
          </el-form-item>
        </div>
      </el-form>
    </div>
  </div>
</template>

<style scoped lang="scss">
  :deep(.el-form-item) {
    margin: 0;
  }

  .user-select-popover-trigger-el {
    cursor: pointer;
    height: 28px;
    line-height: 28px;
    display: flex;
    align-items: center;
  }

  .user-select-wrapper {
    .close-btn {
      display: flex;
      justify-content: flex-end;
      margin-bottom: 12px;

      .iconfont {
        width: 24px;
        height: 24px;
        display: flex;
        justify-content: center;
        align-items: center;
        cursor: pointer;

        &:hover {
          background-color: #f5f7fa;
        }
      }
    }

    .user-select {
      max-height: 350px;
      overflow: auto;

      .customer-info {
        display: flex;
        height: 32px;
        column-gap: 12px;
        cursor: pointer;

        &:hover {
          background-color: #f5f7fa;
        }

        .customer-name {
          line-height: 32px;
          width: 160px;
          text-align: right;
        }

        .customer-phone {
          line-height: 32px;
        }
      }
    }
  }

  .receipt-info-return-factory-create-wrapper {
    .header {
      display: flex;
      align-items: center;

      .title {
        font-size: 14px;
        padding-left: 6px;
        border-left: 3px solid $primaryColor;
        font-weight: bold;
      }

      :deep(.el-switch) {
        height: 16px;
        margin-left: 7px;
        margin-right: 2px;
      }

      .iconfont {
        color: $secondColor2;
      }
    }

    .form {
      :deep(.el-form) {
        display: grid;
        grid-template-columns: repeat(auto-fill, 440px);
        column-gap: 100px;
        margin-top: 18px;
        row-gap: 18px;
        padding: 0 38px;

        .el-form-item {
          .el-form-item__label {
            height: 16px;
            line-height: 16px;
            margin: 0 0 3px 0;
          }

          .el-form-item__content {
            width: 100%;

            .el-form-item__error {
              padding: 0;
              margin: 3px 0 0 0;
            }
          }
        }

        .address-parser {
          .el-form-item__content {
            display: flex;
            flex-direction: row;
            column-gap: 12px;
            align-items: center;
            height: fit-content;

            .el-textarea {
              flex: 1;

              .el-textarea__inner {
                width: 100% !important;
                min-height: 95px !important;
                max-height: 140px !important;
              }
            }
          }
        }

        .customer-name-phone,
        .customer-address,
        .config {
          display: flex;
          flex-direction: column;
          row-gap: 18px;
        }

        .config {
          .is-same-to-customer-address {
            display: flex;
            width: 100%;
            column-gap: 5px;

            .iconfont {
              height: 28px;
              line-height: 28px;
              color: $secondColor2;
            }
          }

          .el-select {
            width: 382px;
          }
        }

        .customer-name-phone {
          .el-input-group__append {
            width: 30px;
            padding: 0;

            .el-select__wrapper {
              padding: 0;
              justify-content: center;

              &:hover {
                box-shadow: 0 1px 0 0 var(--el-input-border-color) inset,
                  0 -1px 0 0 var(--el-input-border-color) inset,
                  -1px 0 0 0 var(--el-input-border-color) inset !important;
              }

              .el-select__selection {
                display: none;
              }

              .el-select__suffix {
                .el-icon {
                  color: #a8abb2;
                }
              }
            }
          }
        }

        .customer-address {
          .el-textarea {
            .el-textarea__inner {
              width: 100% !important;
              height: 28px;
              min-height: 28px !important;
              max-height: 100px !important;
            }
          }
        }
      }
    }
  }
</style>
